﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace _4_BombingCuboids
{
    /*
     * You are given a rectangular cuboid of size W (width), H (height) and D (depth) consisting of W * H * D cubes, each colored in some color.
     * Each color is denoted by a unique capital letter from the Latin alphabet: 'Y' is yellow, 'R' is red, 'B' is blue, 'G' green, etc. 
     * When a bomb with power p is detonated at certain position {w, h, d} inside the cuboid 
     * it destroys all the cubes around it which are located at distance ≤ p from the bomb, while all other cubes remain unaffected.
     *  After a detonation the destroyed cubes leave an empty space in the cuboid and the cubes staying above them fall down due to the gravitation and fill the empty space.
     *  The fall down process moves the cubes to smaller coordinates by the 'height' axis.
     *  The distance between the bomb and given cube is calculated as standard Euclidian distance in the 3D space from the bomb's center to the given cube's center. 
     *  For example, the distance between a bomb located at position {5, 6, 2} and the cube at position {3, 0, 4} is approximately 6.63324958.
     */
    class BombingCuboids
    {
        public static readonly char[] SPACE = new char[] { ' ' };
        static readonly char BOMBED_CELL = '#';
        static char[, ,] cuboid;
        static int W, H, D;
        static SortedList<char, int> destroyed = new SortedList<char, int>();

        static void Main(string[] args)
        {
            //At the first line 3 integers W, H and D are given separated by a space
            String dimensionsInput = Console.ReadLine();
            String[] dimensionsArr = dimensionsInput.Split(SPACE);
            W = int.Parse(dimensionsArr[0]);
            H = int.Parse(dimensionsArr[1]);
            D = int.Parse(dimensionsArr[2]);
            cuboid = new char[W, H, D];
            /*
             * At the next H lines the colors of the cubes in the cuboid are given as 
             * D sequences of exactly W letters. 
             * Each sequence of W letters is separated from the next with a single space
             */
            for (int i = 0; i < H; i++)
            {
                String dSequences = Console.ReadLine();
                String[] sequencesOfWLetters = dSequences.Split(SPACE);
                for (int j = 0; j < D; j++)
                {
                    string letterSeq = sequencesOfWLetters[j];
                    char[] colors = letterSeq.ToCharArray();
                    for (int k = 0; k < W; k++)
                    {
                        cuboid[k, i, j] = colors[k];
                    }
                }
            }
            /*
             * At the next line a single integer N is given – the number of bombs.
             * At the next N lines the bombs are given, each as a sequence of 4 integers separated by a space: w, h, d, and p.
             */
            int bombCount = int.Parse(Console.ReadLine());
            Bomb[] bombs = new Bomb[bombCount];
            for (int i = 0; i < bombCount; i++)
            {
                bombs[i] = new Bomb(Console.ReadLine());
            }

            foreach (Bomb b in bombs)
            {
                Detonate(b);
                //Console.WriteLine("* * * * * * B O O O O M ! * * * * * * * ");
                //Print();
                FallThrough(b);
                //Print();
            }

            int totalDestroyed = 0;
            foreach (int count in destroyed.Values)
            {
                totalDestroyed += count;
            }
            Console.WriteLine(totalDestroyed);

            foreach (KeyValuePair<char, int> pair in destroyed)
            {
                Console.WriteLine("{0} {1}", pair.Key, pair.Value);
            }
        }


        private static void Detonate(Bomb b)
        {
            int areaOfEffectWmin = b.GetAreaOfEffectStartW();
            int areaOfEffectWmax = b.GetAreaOfEffectEndW(W);
            int areaOfEffectDmin = b.GetAreaOfEffectStartD();
            int areaOfEffectDmax = b.GetAreaOfEffectEndD(D);
            int areaOfEffectHmin = b.GetAreaOfEffectStartH();
            int areaOfEffectHmax = b.GetAreaOfEffectEndH(H);

            for (int i = areaOfEffectWmin; i <= areaOfEffectWmax; i++)
            {
                for (int j = areaOfEffectHmin; j <= areaOfEffectHmax; j++)
                {
                    for (int k = areaOfEffectDmin; k <= areaOfEffectDmax; k++)
                    {
                        if (b.IsInRange(i, j, k))
                        {
                            char c = cuboid[i, j, k];
                            if (c != BOMBED_CELL)
                            {
                                int count;
                                if (destroyed.TryGetValue(c, out count))
                                {
                                    destroyed[c] = count + 1;
                                }
                                else
                                {
                                    destroyed.Add(c, 1);
                                }
                                cuboid[i, j, k] = BOMBED_CELL;
                            }
                        }
                    }
                }
            }

        }

        /*All blocks "fall through" along the H axis
         That means for every null block all above it fall down one index along H;
         */
        private static void FallThrough(Bomb b)
        {
            int areaOfEffectWmin = b.GetAreaOfEffectStartW();
            int areaOfEffectWmax = b.GetAreaOfEffectEndW(W);
            int areOfEffectDmin = b.GetAreaOfEffectStartD();
            int areOfEffectDmax = b.GetAreaOfEffectEndD(D);


            for (int i = areaOfEffectWmin; i <= areaOfEffectWmax; i++)
            {
                for (int k = areOfEffectDmin; k <= areOfEffectDmax; k++)
                {
                    for (int j = H - 1; j >= 0; j--)
                    {
                        if (cuboid[i, j, k] != BOMBED_CELL)
                        {
                            continue;
                        }
                        else
                        {
                            int nullsCount = 0;
                            while (j - nullsCount >= 0 && cuboid[i, j - nullsCount, k] == BOMBED_CELL)
                            {
                                nullsCount++;
                            }
                            for (int swapIndex = j+1; swapIndex < H; swapIndex++)
                            {
                                cuboid[i, swapIndex - nullsCount, k] = cuboid[i, swapIndex, k];
                                cuboid[i, swapIndex, k] = BOMBED_CELL;
                            }
                            j -= --nullsCount;
                        }
                    }

                }
            }
        }


        static void Print() {
            for (int k = 0; k < D; k++)
            {
                for (int j = H-1; j >= 0; j--)
                {
                    for (int i = 0; i < W; i++)
                    {
                        Console.Write("{0} ", cuboid[i, j, k]);
                    }
                    Console.WriteLine();
                }
                Console.WriteLine();
            }
            Console.WriteLine("------------------------------------------------------------------------------");
        
        }
    }

    public struct Bomb
    {
        int w, h, d, p;

        //bombs are given as a sequence of 4 integers separated by a space: w, h, d, and p.
        public Bomb(String input)
        {
            String[] data = input.Split(new char[] { ' ' });
            w = int.Parse(data[0]);
            h = int.Parse(data[1]);
            d = int.Parse(data[2]);
            p = int.Parse(data[3]);
        }

        public Boolean IsInRange(int targetW, int targetH, int targetD)
        {

            double distance = Math.Sqrt(Math.Pow(targetW - w, 2) + Math.Pow(targetH - h, 2) + Math.Pow(targetD - d, 2));

            return distance <= p;
        }

        public int GetAreaOfEffectStartW()
        {
            return w - p < 0 ? 0 : w - p;
        }

        public int GetAreaOfEffectEndW(int W)
        {
            return w + p >= W ? W - 1 : w + p;
        }

        public int GetAreaOfEffectStartD()
        {
            return d - p < 0 ? 0 : d - p;
        }

        public int GetAreaOfEffectEndD(int D)
        {
            return d + p >= D ? D - 1 : d + p;
        }

        public int GetAreaOfEffectStartH()
        {
            return h - p < 0 ? 0 : h - p;
        }

        public int GetAreaOfEffectEndH(int H)
        {
            return h + p >= H ? H - 1 : h + p;
        }
    }
}
